home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 7 / FM Towns Free Software Collection 7.iso / ms_dos / thmake / thcal.c < prev    next >
C/C++ Source or Header  |  1993-11-30  |  2KB  |  121 lines

  1.  
  2. /*
  3.     雪辱の逆襲戦い“THcal”
  4.  
  5.         By 五味(93/06/17~93/07/14)
  6.  
  7. */
  8.  
  9. #include <stdio.h>
  10. #include <string.h>
  11. #include <stdlib.h>
  12. #include <ctype.h>
  13.  
  14. #define    TRUE    0
  15. #define    FALSE    -1
  16.  
  17. #define    FULL    (void *)0xffff
  18. #define    ENZ    5
  19.  
  20.     char    *mark[]={ "*","/","+","-","^","EOM"    };
  21.     char    mpri[]=    {  20, 20, 30, 30, 10,  99    };
  22.     char    *eos;
  23.     int    isc;
  24.  
  25. int expr(char *,int,int);
  26. int prex(char *,int);
  27.  
  28.  
  29. int prex(char *siki,int enz)
  30. {
  31.     char    *p,k;
  32.     int    tval;
  33.  
  34.     for( ; *siki==' ' || *siki=='\t' ; siki++ );
  35.  
  36.     if( *siki=='(' ) {
  37.         for( p=(++siki),k=1 ; k>0 ; p++ )
  38.                 if( *p=='(' )    k++;
  39.             else    if( *p==')' )    k--;
  40.             else    if( *p=='\0') {
  41.                     printf(" 括弧が異常です.\n");
  42.                     exit(1);
  43.                 }
  44.         *(p-1)='\0';
  45.         tval=prex(siki,ENZ);
  46.         if( p>eos )    eos=p;
  47.         siki=p;
  48.     }else{
  49.         tval=atoi(siki++);
  50.         for( ; isdigit(*siki) ; siki++ );
  51.         if( siki>eos )    eos=siki;
  52.     }
  53.  
  54.     tval=expr(siki,enz,tval);
  55.     while( isc ) {
  56.         isc=0;
  57.         tval=expr(eos,enz,tval);
  58.     }
  59.     return tval;
  60. }
  61.  
  62. int expr(char *siki,int enz,int tval)
  63. {
  64.     int    i;        /* 汎用(ループ等)    */
  65.     int    enzk;        /* 掛かっている演算子    */
  66.     int    val;        /* 一時的な値        */
  67.     char    *lesp,*tmp;    /* 演算子のポインタ    */
  68.  
  69.     for( i=0,enzk=ENZ,lesp=FULL ; i<ENZ ; i++ ) {
  70.         if( (tmp=strstr(siki,mark[i]))!=NULL && tmp<lesp ) {
  71.             lesp=tmp;
  72.             enzk=i;
  73.         }            /* 後ろの演算子を割り出す    */
  74.     }
  75.  
  76.     if( enzk!=ENZ && mpri[enzk]<mpri[enz] ) {    /* 演算子ごとの演算 */
  77.         val=prex(lesp+strlen(mark[enzk]),enzk);
  78.         switch(enzk) {
  79.         case 0:    val=tval*val;
  80.             break;
  81.         case 1:    val=tval/val;
  82.             break;
  83.         case 2:    val=tval+val;
  84.             break;
  85.         case 3:    val=tval-val;
  86.             break;
  87.         case 4:    for( i=val,val=1 ; i>0 ; i-- )
  88.                 val=val*tval;
  89.             break;
  90.         }
  91.         isc=1;
  92.     }else{
  93.         val=tval;
  94.     }
  95.  
  96.     return val;
  97. }
  98.  
  99. int calc(char *str)
  100. {
  101.     isc=0;
  102.     return prex(eos=strdup(str),ENZ);
  103. }
  104.  
  105. void main(int argc,char *argv[])
  106. {
  107.     if( argc==1 ) {
  108.         printf(    " 'THcal' 簡易計算機 v1.0a\n"
  109.             " (c) H.gomi  1993/07/14\n"    );
  110.         return;
  111.     }
  112.  
  113.     if( argc>2 ) {
  114.         printf(" 式に空白は挟めません.\n");
  115.         return;
  116.     }
  117.  
  118.     printf(    "\n"
  119.         "\t'%s'=%d\n",argv[1],calc(argv[1])    );
  120. }
  121.